import asyncio
import os
import json
from typing import Union

from playwright.async_api import async_playwright
import requests

from action import ActionType
from autoScript.OkxAutoScript import OkxAutoScriptPage
from script import Script, ScriptInterpreter, ScriptInterpreterReplace
from action_executor import Executor
from steps import BaseStep, ClickStep, GotoStep, InputStep, SleepStep, ScreenshotStep, WaitForSelectorStep, ExecStep, \
    JsEvaluateStep

# 自动收集所有直接子类
AllStepTypes = tuple(BaseStep.__subclasses__())
StepType = Union[AllStepTypes]


# 解析步骤数据
def parseSteps(steps: list[dict]) -> list[BaseStep]:
    step_factory = {
        ActionType.CLICK.name: ClickStep,
        ActionType.GOTO.name: GotoStep,
        ActionType.INPUT.name: InputStep,
        ActionType.SLEEP.name: SleepStep,
        ActionType.SCREENSHOT.name: ScreenshotStep,
        ActionType.WAIT_FOR_SELECTOR.name: WaitForSelectorStep,
        ActionType.EXEC.name: ExecStep,
        ActionType.JSEVALUATE.name: JsEvaluateStep
    }
    parsed_steps = []
    for step in steps:
        step_class = step_factory.get(step["action"])
        if step_class:
            parsed_steps.append(step_class(**step))
        else:
            raise ValueError(f"未知操作类型: {step['action']}")
    return parsed_steps


def dict_to_script_interpreter(d: dict) -> ScriptInterpreter:
    replace_dict = d.get('replaces', [])
    replace_obj_list = []
    for replace_dict in replace_dict:
        replace_obj = ScriptInterpreterReplace(
            url=replace_dict.get('url', ''),
            match=replace_dict.get('match', ''),
            content=replace_dict.get('content', ''),
            encodeing=replace_dict.get('encodeing', 'utf-8')
        )
        replace_obj_list.append(replace_obj)
    return ScriptInterpreter(
        match=d.get('match', ''),
        replaces=replace_obj_list
    )


# 加载脚本数据
def load_script():
    scripts = []
    path = "./scripts"
    for file in os.listdir(path):
        if file.endswith(".json"):
            with open(os.path.join(path, file), "r", encoding="utf-8") as f:
                data = json.load(f)
                scripts.append(Script(data["name"], data["url"], parseSteps(data["steps"]),
                                      dict_to_script_interpreter(data.get("interpreter"))))
    return Executor(scripts)


def start_browser(user_id: str):
    browserReq = requests.get(url=f"http://local.adspower.net:50325/api/v1/browser/start?user_id={user_id}")
    return browserReq.json()


def get_browser():
    browserReq = requests.get(url="http://local.adspower.net:50325/api/v1/user/list")
    return browserReq.json()['data']['list']


# 主程序
async def main():
    browsers = get_browser()
    for browser in browsers:
        startContext = start_browser(browser['user_id'])
        async with async_playwright() as p:
            browserConnect = await p.chromium.connect_over_cdp(f"http://{startContext['data']['ws']['selenium']}/")
            context = browserConnect.contexts[0]

            async def on_new_page(new_page):
                try:
                    print("新页面打开:", new_page.url)
                    await new_page.wait_for_load_state("load")
                    title = await new_page.title()
                    print("新页面标题:", title)
                    # 自动处理欧易钱包
                    if title == 'OKX Wallet':
                        await OkxAutoScriptPage(new_page).run()
                except Exception as e:
                    print("页面监听异常", e)

            context.on("page", on_new_page)
            # page = context.pages[0]
            # await page.goto("https://www.baidu.com")
            # await page.screenshot(path="baidu.png")
            # await page.close()
            executor = load_script()
            await executor.run(context)


asyncio.run(main())
